"use strict";

const Service = require("egg").Service;

class ProductService extends Service {
  /**
   * 获取商品列表
   * @param {Object} query 查询条件
   * @param {Number} page 页码
   * @param {Number} pageSize 每页数量
   * @returns {Promise<Array>} 商品列表
   */
  async getList(query = {}, page = 1, pageSize = 10) {
    const { Op } = this.app.Sequelize;
    const where = {};

    if (query.name) {
      where.name = { [Op.like]: `%${query.name}%` };
    }
    if (query.description) {
      where.description = { [Op.like]: `%${query.description}%` };
    }

    if (query.category_id) {
      where.category_id = query.category_id;
    }

    if (query.brand_id) {
      where.brand_id = query.brand_id;
    }

    if (query.status !== undefined) {
      where.status = query.status;
    }

    if (query.is_hot !== undefined) {
      where.is_hot = query.is_hot;
    }

    if (query.is_new !== undefined) {
      where.is_new = query.is_new;
    }

    if (query.is_recommend !== undefined) {
      where.is_recommend = query.is_recommend;
    }

    // 价格范围查询
    if (query.min_price) {
      where.price = { [Op.gte]: query.min_price };
    }

    if (query.max_price) {
      if (where.price) {
        where.price = { ...where.price, [Op.lte]: query.max_price };
      } else {
        where.price = { [Op.lte]: query.max_price };
      }
    }

    // 排序
    let order = [
      ["sort_order", "ASC"],
      ["id", "DESC"],
    ];
    if (query.sort_field && query.sort_type) {
      order = [[query.sort_field, query.sort_type.toUpperCase()]];
    }

    const result = await this.ctx.model.Product.findAndCountAll({
      where,
      offset: (page - 1) * pageSize,
      limit: pageSize,
      order,
      include: [
        { model: this.ctx.model.Category, attributes: ["id", "name"] },
        { model: this.ctx.model.Brand, attributes: ["id", "name", "logo"] },
        {
          model: this.ctx.model.ProductImage,
          attributes: ["id", "image_url", "sort_order"],
        },
      ],
      distinct: true, // 添加这个选项
    });

    return {
      list: result.rows,
      total: result.count,
      page: page,
      pageSize: pageSize,
    };
  }

  /**
   * 获取热门商品
   * @param {Number} limit 获取数量
   * @returns {Promise<Array>} 热门商品列表
   */
  async getHotProducts(limit = 10) {
    return this.ctx.model.Product.findAll({
      where: { is_hot: true, status: true },
      order: [["sales", "DESC"]],
      limit,
      include: [
        {
          model: this.ctx.model.ProductImage,
          attributes: ["id", "image_url", "sort_order"],
        },
      ],
    });
  }

  /**
   * 获取新品商品
   * @param {Number} limit 获取数量
   * @returns {Promise<Array>} 新品商品列表
   */
  async getNewProducts(limit = 10) {
    return this.ctx.model.Product.findAll({
      where: { is_new: true, status: true },
      order: [["created_at", "DESC"]],
      limit,
      include: [
        {
          model: this.ctx.model.ProductImage,
          attributes: ["id", "image_url", "sort_order"],
        },
      ],
    });
  }

  /**
   * 获取推荐商品
   * @param {Number} limit 获取数量
   * @returns {Promise<Array>} 推荐商品列表
   */
  async getRecommendProducts(limit = 10) {
    return this.ctx.model.Product.findAll({
      where: { is_recommend: true, status: true },
      order: [
        ["sort_order", "ASC"],
        ["id", "DESC"],
      ],
      limit,
      include: [
        {
          model: this.ctx.model.ProductImage,
          attributes: ["id", "image_url", "sort_order"],
        },
      ],
    });
  }

  /**
   * 根据ID获取商品详情
   * @param {Number} id 商品ID
   * @returns {Promise<Object>} 商品详情
   */
  async getById(id) {
    return this.ctx.model.Product.findByPk(id, {
      include: [
        { model: this.ctx.model.Category, attributes: ["id", "name"] },
        {
          model: this.ctx.model.Brand,
          attributes: ["id", "name", "logo", "description"],
        },
        {
          model: this.ctx.model.ProductImage,
          attributes: ["id", "image_url", "sort_order"],
          order: [["sort_order", "ASC"]],
        },
      ],
    });
  }

  /**
   * 创建商品
   * @param {Object} data 商品数据
   * @returns {Promise<Object>} 创建结果
   */
  async create(data) {
    const { images = [], skus = [] } = data;

    // 生成SKU ID
    if (skus && skus.length > 0) {
      skus.forEach((sku) => {
        if (!sku.id) {
          sku.id = `SKU-${this.ctx.helper.uuid().slice(0, 8)}`;
        }
      });
    }

    // 计算起售价
    if (skus && skus.length > 0) {
      data.price = Math.min(...skus.map((sku) => sku.price));
      // 计算总库存
      data.stock = skus.reduce((total, sku) => total + sku.stock, 0);
    }

    // 开始事务
    const transaction = await this.ctx.model.transaction();

    try {
      // 创建商品
      const product = await this.ctx.model.Product.create(data, {
        transaction,
      });

      // 创建商品图片
      if (images.length > 0) {
        const imageList = images.map((image, index) => ({
          product_id: product.id,
          sort_order: index,
          image_url: image,
        }));
        await this.ctx.model.ProductImage.bulkCreate(imageList, {
          transaction,
        });
      }

      // 创建商品规格
      // if (specs.length > 0) {
      //   const specList = specs.map((spec) => ({
      //     ...spec,
      //     product_id: product.id,
      //   }));
      //   await this.ctx.model.ProductSpec.bulkCreate(specList, { transaction });
      // }

      // 提交事务
      await transaction.commit();

      return product;
    } catch (error) {
      // 回滚事务
      await transaction.rollback();
      throw error;
    }
  }

  /**
   * 更新商品
   * @param {Number} id 商品ID
   * @param {Object} data 商品数据
   * @returns {Promise<Number>} 更新结果
   */
  async update(id, data) {
    const { images = [], skus = [] } = data;

    // 生成SKU ID
    if (skus && skus.length > 0) {
      skus.forEach((sku) => {
        if (!sku.id) {
          sku.id = `SKU-${this.ctx.helper.uuid().slice(0, 8)}`;
        }
      });
    }

    // 计算起售价
    if (skus && skus.length > 0) {
      data.price = Math.min(...skus.map((sku) => sku.price));
      // 计算总库存
      data.stock = skus.reduce((total, sku) => total + sku.stock, 0);
    }

    // 开始事务
    const transaction = await this.ctx.model.transaction();

    try {
      // 更新商品基本信息
      await this.ctx.model.Product.update(data, {
        where: { id },
        transaction,
      });

      // 更新商品图片
      if (images.length > 0) {
        // 删除原有图片
        await this.ctx.model.ProductImage.destroy({
          where: { product_id: id },
          transaction,
        });

        // 创建新图片
        const imageList = images.map((image, index) => ({
          product_id: id,
          image_url: image,
          sort_order: index,
        }));
        await this.ctx.model.ProductImage.bulkCreate(imageList, {
          transaction,
        });
      }

      // 更新商品规格
      // if (specs.length > 0) {
      //   // 删除原有规格
      //   await this.ctx.model.ProductSpec.destroy({
      //     where: { product_id: id },
      //     transaction,
      //   });

      //   // 创建新规格
      //   const specList = specs.map((spec, index) => ({
      //     ...spec,
      //     product_id: id,
      //     sort_order: index,
      //   }));
      //   await this.ctx.model.ProductSpec.bulkCreate(specList, { transaction });
      // }

      // 提交事务
      await transaction.commit();

      return true;
    } catch (error) {
      // 回滚事务
      await transaction.rollback();
      throw error;
    }
  }

  /**
   * 删除商品
   * @param {Number} id 商品ID
   * @returns {Promise<Number>} 删除结果
   */
  async delete(id) {
    // 开始事务
    const transaction = await this.ctx.model.transaction();

    try {
      // 删除商品规格
      // await this.ctx.model.ProductSpec.destroy({
      //   where: { product_id: id },
      //   transaction,
      // });

      // 删除商品图片
      await this.ctx.model.ProductImage.destroy({
        where: { product_id: id },
        transaction,
      });

      // 删除商品
      const result = await this.ctx.model.Product.destroy({
        where: { id },
        transaction,
      });

      // 提交事务
      await transaction.commit();

      return result;
    } catch (error) {
      // 回滚事务
      await transaction.rollback();
      throw error;
    }
  }

  /**
   * 扣减商品库存
   * @param {Number} id 商品ID
   * @param {Number} quantity 扣减数量
   * @returns {Promise<Boolean>} 扣减结果
   */
  async reduceStock(id, quantity) {
    // 开始事务
    const transaction = await this.ctx.model.transaction();

    try {
      // 获取当前库存
      const product = await this.ctx.model.Product.findByPk(id, {
        transaction,
      });

      if (!product) {
        throw new Error("商品不存在");
      }

      if (product.stock < quantity) {
        throw new Error("库存不足");
      }

      // 扣减库存
      await this.ctx.model.Product.update(
        { stock: product.stock - quantity, sales: product.sales + quantity },
        { where: { id }, transaction }
      );

      // 提交事务
      await transaction.commit();

      return true;
    } catch (error) {
      // 回滚事务
      await transaction.rollback();
      throw error;
    }
  }

  /**
   * 扣减商品规格库存
   * @param {Number} specId 规格ID
   * @param {Number} quantity 扣减数量
   * @returns {Promise<Boolean>} 扣减结果
   */
  async reduceSpecStock(specId, quantity) {
    // 开始事务
    const transaction = await this.ctx.model.transaction();

    try {
      // 获取当前规格
      const spec = await this.ctx.model.ProductSpec.findByPk(specId, {
        transaction,
      });

      if (!spec) {
        throw new Error("规格不存在");
      }

      if (spec.stock < quantity) {
        throw new Error("规格库存不足");
      }

      // 扣减规格库存
      await this.ctx.model.ProductSpec.update(
        { stock: spec.stock - quantity },
        { where: { id: specId }, transaction }
      );

      // 同时更新商品总库存
      const product = await this.ctx.model.Product.findByPk(spec.product_id, {
        transaction,
      });
      await this.ctx.model.Product.update(
        { stock: product.stock - quantity, sales: product.sales + quantity },
        { where: { id: spec.product_id }, transaction }
      );

      // 提交事务
      await transaction.commit();

      return true;
    } catch (error) {
      // 回滚事务
      await transaction.rollback();
      throw error;
    }
  }
}

module.exports = ProductService;
